/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package muddb;


import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.Query;
import muddb.entities.CharRace;
import muddb.entities.EquippedLoc;
import muddb.entities.EventLog;
import muddb.entities.Guild;
import muddb.entities.MudItem;
import muddb.entities.MudItemAttr;
import muddb.entities.MudItemClass;
import muddb.entities.MudItemClassAttr;
import muddb.entities.MudPlace;
import muddb.entities.MudPortal;
import muddb.entities.Skill;
import muddb.entities.SkillGroup;
import muddb.entities.SkillGroupProf;
import muddb.entities.SkillProf;
import muddb.entities.UserAccount;
import muddb.entities.UserChar;
import muddb.entities.UserCharItem;
import muddb.entities.UserCharPK;


/**
 *
 * @author keith
 */
public class Main {

  final private DatabaseManager dbm = DatabaseManager.getInstance();
  final private UserChar testUserChar = new UserChar();
  final private Map<String, EquippedLoc> equipMap =
    new TreeMap<String, EquippedLoc>();
  final private MudItem RobeItem = new MudItem();
  private MudPlace origin;


  public Main() {
    dbm.create();
  }


  private void addEquipedLocations() {
    final String[] midlineLocs = new String[]{
      "body", "head", "neck", "throat", "chin",
      "face", "nose", "mouth", "forehead",
      "chest", "back", "stomach"
    };
    final String[] sideLocs = new String[]{
      "eye", "cheek", "ear",
      "arm", "shoulder", "bicep", "elbow", "forearm", "wrist", "hand",
      "thumb", "pointer-finger", "index-finger", "ring-finger", "pinkey-finger",
      "leg", "thigh", "knee", "shin", "ankle", "foot",
      "big-toe", "pointer-toe", "index-toe", "ring-toe", "pinkey-toe"
    };
    final List<String> locs = new ArrayList<String>(
      Arrays.asList( midlineLocs ) );


    for ( String side : new String[]{ "right", "left" } ) {
      for ( String p : sideLocs ) {
        final String bodyPart = side + "-" + p;

        locs.add( bodyPart );
      }
    }

    final EntityManager em = dbm.getEntityManager();
    final EntityTransaction trans = em.getTransaction();

    trans.begin();

    for ( String p : locs ) {
      EquippedLoc el = new EquippedLoc();
      el.setEquippedLocName( p );

      equipMap.put( el.getEquippedLocName(), el );
      em.persist( el );
    }

    trans.commit();
    em.close();
  }


  private void addEvent() {
    final EntityManager em = dbm.getEntityManager();
    final EntityTransaction trans = em.getTransaction();
    
    trans.begin();

    em.persist( new EventLog( "This incredible event occurred!") );
    
    trans.commit();
    em.close();
  }


  private void addGuild() {
    final EntityManager em = dbm.getEntityManager();
    final EntityTransaction trans = em.getTransaction();

    final UserChar uc =
      em.find( UserChar.class,
               new UserCharPK( testUserChar.getUserId(),
                               testUserChar.getCharId() ) );

    trans.begin();

    final Guild guild = new Guild( "Grad Student" );
    final List<UserChar> users = new ArrayList<UserChar>();
    guild.setUserCharCollection( users );
    users.add( uc );

    em.persist( guild );
    trans.commit();
    em.close();
  }


  private void addItem() {
    final MudItemClass itemClass = new MudItemClass();
    itemClass.setItemDesc( "robe" );

    final EntityManager em = dbm.getEntityManager();
    final EntityTransaction trans = em.getTransaction();

    trans.begin();
    em.persist( itemClass );
    trans.commit();

    final MudItemClassAttr itemClassAttr = new MudItemClassAttr();
    itemClassAttr.setItemClassId( itemClass.getItemClassId() );
    itemClassAttr.setItemClassAttrName( "color" );

    trans.begin();
    em.persist( itemClassAttr );
    trans.commit();

    RobeItem.setItemClassId( itemClass.getItemClassId() );

    trans.begin();
    em.persist( RobeItem );
    trans.commit();

    final MudItemAttr itemAttr = new MudItemAttr();
    itemAttr.setItemClassId( RobeItem.getItemClassId() );
    itemAttr.setItemId( RobeItem.getItemId() );
    itemAttr.setItemClassAttrId( itemClassAttr.getItemClassAttrId() );
    itemAttr.setItemAttrVal( "black" );

    trans.begin();
    em.persist( itemAttr );
    trans.commit();
    em.close();
  }


  private void addPlaces() {
    final EntityManager em = dbm.getEntityManager();
    final EntityTransaction trans = em.getTransaction();
    final List<MudPlace> places = new ArrayList<MudPlace>();


    trans.begin();

    for ( String p : new String[]{ "ET 146", "Kettler Bar & Grill" } ) {
      MudPlace place = new MudPlace();
      place.setPlaceName( p );
      place.setShortDescr( "Short description for " + p );

      em.persist( place );
      places.add( place );
    }

    trans.commit();

    for ( int idx = 1, len = places.size(); idx < len; idx++ ) {
      // connect the the place at 'idx' with the place at 'idx - 1'
      final MudPlace startPlace = places.get( idx - 1 );
      final MudPlace endPlace = places.get( idx );


      final MudPortal outPortal = new MudPortal( startPlace, endPlace );
      outPortal.connectPlaces();
      final MudPortal inPortal = new MudPortal( endPlace, startPlace );
      inPortal.connectPlaces();
    }
    trans.begin();
    for ( MudPlace p : places ) {
      em.persist( p );
    }
    trans.commit();

    origin = places.get( 0 );
    em.close();
  }


  private void addSkills() {
    final EntityManager em = dbm.getEntityManager();
    final EntityTransaction trans = em.getTransaction();

    final UserChar uc =
      em.find( UserChar.class,
               new UserCharPK( testUserChar.getUserId(),
                               testUserChar.getCharId() ) );

    trans.begin();

    final SkillGroup skg = new SkillGroup( "coder" );
    em.persist( skg );

    trans.commit();

    trans.begin();
    final Collection<Skill> skills = new ArrayList<Skill>();
    skg.setSkillCollection( skills );
    final Skill cPlusPlus = new Skill( "c++" );
//    cPlusPlus.setSkillGroup( skg );
    cPlusPlus.setSkillGrpId( skg.getSkillGrpId() );
    skills.add( cPlusPlus );
    em.persist( skg );
    trans.commit();

    trans.begin();
    SkillGroupProf skgp = new SkillGroupProf( uc.getUserId(), uc.getCharId(), skg.getSkillGrpId());
    SkillProf skp = new SkillProf( uc.getUserId(), uc.getCharId(), cPlusPlus.getSkillGrpId(), cPlusPlus.getSkillId());
    
    em.persist( skgp );
    em.persist( skp );
    
    trans.commit();

    em.close();
  }


  /**
   * Add a UserAccount, UserChar, and CharRace.
  
   */
  private void addUser() {

    final CharRace race1 = new CharRace();
    race1.setRaceName( "alloyboyz" );

    final UserAccount user1 = new UserAccount();
    user1.setUserLogon( "keith" );
    user1.setUserName( "Keith Shie" );
    user1.setPermission( PermisionLevelEnum.PLAYER );

    final EntityManager em = dbm.getEntityManager();
    final EntityTransaction trans = em.getTransaction();

    trans.begin();

    em.persist( user1 );
    em.persist( race1 );

    trans.commit();

    System.out.println( "raceId: " + race1.getRaceId() );
    System.out.println( "userId: " + user1.getUserId() );

    final List<UserChar> charList = new ArrayList<UserChar>();

    testUserChar.setCharName( "Tin Man" );
    testUserChar.setRaceId( race1 );
    testUserChar.setUserAccount( user1 );
    testUserChar.setUserId( user1.getUserId() );
    charList.add( testUserChar );
    user1.setUserCharCollection( charList );

    trans.begin();
    em.persist( user1 );
    trans.commit();
    em.close();
  }


  private void addUserCharItem() {
    final EntityManager em = dbm.getEntityManager();
    final EntityTransaction trans = em.getTransaction();

    trans.begin();

    final UserCharItem charItem = new UserCharItem( testUserChar, RobeItem );
    final EquippedLoc e = equipMap.get( "body" );

    charItem.setEquippedLocId( e );
    em.persist( charItem );
    trans.commit();
    em.close();
  }


  /**
   * Show the single character race with an Id of '1'.
   */
  private void findCharRace() {

    final EntityManager em = dbm.getEntityManager();
    final Query qry =
      em.createQuery( "SELECT c FROM CharRace c WHERE c.raceId = :raceId" );
    qry.setParameter( "raceId", 1 );
    CharRace result = (CharRace) qry.getSingleResult();

    System.out.println(
      "\tCharRace: " + result.toString() + ", name: " + result.getRaceName() );
  }


  private void placeChar() {
    final EntityManager em = dbm.getEntityManager();
    final EntityTransaction trans = em.getTransaction();

    final UserChar uc =
      em.find( UserChar.class,
               new UserCharPK( testUserChar.getUserId(),
                               testUserChar.getCharId() ) );
    final MudPlace mp = em.find( MudPlace.class, origin.getPlaceId() );

    trans.begin();

//    uc.setPlace( mp );
    em.persist( uc );
    final List<UserChar> chars = new ArrayList<UserChar>();
    chars.add( uc );
    mp.setUserCharCollection( chars );
    em.persist( mp );
    trans.commit();
    em.close();
  }


  /**
   * Show list of user characters with the name of "Tin Man".
   */
  private void showUserChars() {

    final EntityManager em = dbm.getEntityManager();
    final Query qry = em.createNamedQuery( "UserChar.findByCharName" );
    qry.setParameter( "charName", "Tin Man" );
    List<UserChar> result = qry.getResultList();

    for ( UserChar uc : result ) {
      System.out.println( "UserChar: " + uc.toString() );
      final UserAccount ua = uc.getUserAccount();
      System.out.println(
        "\tUserAccount: " + ua.toString() + ", name: " + ua.getUserName() );
      final CharRace cr = uc.getRaceId();
      System.out.println(
        "\tCharRace: " + cr.toString() + ", name: " + cr.getRaceName() );
    }
  }


  /**
   * @param args the command line arguments
   */
  public static void main( String[] args ) {

    final Main m = new Main();

    m.addUser();
    m.addItem();
    m.addEquipedLocations();
    m.addUserCharItem();
    m.addPlaces();
    m.placeChar();
    m.addGuild();
    m.addSkills();
    m.addEvent();

    m.showUserChars();
    m.findCharRace();
  }
}
